
package org.lemon.common;

import java.io.IOException;
import java.text.MessageFormat;

/**
 * @since 2024-12-07 18:13
 */
public class DBException extends RuntimeException{

    private static final int IO_EXCEPTION_2 = 90001;
    private int errorCode;

    public static DBException create(int errorCode,String message, Object ... args){
        String msg = formatMessage(errorCode,message,args);
        DBException dbException = new DBException(errorCode,msg);
        initCause(dbException, args);
        return dbException;
    }

    public DBException(int errorCode,String message) {
        super(message);
        this.errorCode = errorCode;
    }

    public DBException(Throwable cause, int errorCode) {
        super(cause);
        this.errorCode = errorCode;
    }

    /**
     * Convert an IO exception to a store exception.
     *
     * @param e the root cause
     * @param message the message or null
     * @return the database exception object
     */
    public static DBException convertIOException(IOException e, String message) {
        if (message == null) {
            Throwable t = e.getCause();
            if (t instanceof DBException) {
                return (DBException) t;
            }
            return new DBException(IO_EXCEPTION_2 ,message);
        }
        return new DBException(e,IO_EXCEPTION_2);
    }

    private static <T extends Exception> T initCause(T e, Object... arguments) {
        int size = arguments.length;
        if (size > 0) {
            Object o = arguments[size - 1];
            if (o instanceof Throwable) {
                e.initCause((Throwable) o);
            }
        }
        return e;
    }

    /**
     * Format an error message.
     *
     * @param errorCode the error code
     * @param message the message
     * @param arguments the arguments
     * @return the formatted message
     */
    public static String formatMessage(int errorCode, String message,
        Object... arguments) {
        // convert arguments to strings, to avoid locale specific formatting
        arguments = arguments.clone();
        for (int i = 0; i < arguments.length; i++) {
            Object a = arguments[i];
            if (!(a instanceof Exception)) {
                String s = a == null ? "null" : a.toString();
                if (s.length() > 1000) {
                    s = s.substring(0, 1000) + "...";
                }
                arguments[i] = s;
            }
        }
        return MessageFormat.format(message, arguments) +
            " [" + errorCode + "]";
    }
}
